#pragma once
#include<iostream>
#include"reve_iterator.hpp"
using namespace std;
namespace hcc
{
    template<class T>
    //链表节点
    struct node
    {
        node(const T& x=T())
            : val(x)
            , next(nullptr)
            , prev(nullptr)
        {}
        T val;
        node *next;
        node *prev;
    };
    //迭代器
    template<class T ,class ref ,class ptr>
    struct list_iterator
    {
        typedef node<T> listnode;
        typedef list_iterator<T,ref,ptr> iterator;
        listnode *nodee;
        list_iterator(listnode *newnode)
            :nodee(newnode)
        {}
        iterator& operator++()
        {
            nodee=nodee->next;
            return *this;
        }
        iterator operator++(int)
        {
            iterator tem(*this);
            ++(*this);
            return tem;
        }
        iterator& operator--()
        {
            nodee=nodee->prev;
            return *this;
        }
        iterator operator--(int)
        {
            iterator tem(*this);
            --(*this);
            return tem;
        }
        bool operator!=(const iterator& x)const
        {
            return nodee!=x.nodee;
        }
        bool operator==(const iterator& x)const
        {
            return !(*this!=x);
        }
        ref operator*()const
        {
            return nodee->val;
        }
        //第一种写法：
        // ptr operator->()
        // {
        //     return &(nodee->val);
        // }
        //第二种写法：
        ptr operator->()const
        {
            return &(operator*());
        }
    };

    //链表
    template<class T>
    class list
    {
        public:
            typedef node<T> listnode;
            typedef list_iterator<T,T&,T*> iterator;
            typedef list_iterator<T,const T&,const T*> const_iterator;
            typedef reve_iterator<iterator,T&,T*> riterator;
            typedef reve_iterator<iterator,const T&,const T*> const_riterator;
            list()
                :head(new listnode)
            {
                head->next=head;
                head->prev=head;
            }
            template<class Iterator>
            explicit list(Iterator Begin,Iterator End)
                : head(new listnode)
            {
                init();
                while(Begin!=End)
                {
                    push_back(*Begin);
                    Begin++;
                }
            }
            list(const list<T>& x)
            {
                list<T> tem(x.begin(),x.end());
                swap(tem);
            }
            list<T>& operator=(list<T> x)
            {
                swap(x);
                return *this;
            }
            iterator begin()
            {
                return iterator(head->next);
            }
            iterator end()
            {
                return iterator(head);
            }
            const_iterator begin()const
            {
                return const_iterator(head->next);
            }
            const_iterator end()const
            {
                return const_iterator(head);
            }
            riterator rbegin()
            {
                return riterator(head);
            }
            riterator rend()
            {
                return riterator(head->next);
            }
            const_riterator rbegin()const
            {
                return const_riterator(head);
            }
            const_riterator rend()const
            {
                return const_riterator(head->next);
            }
            void swap(list<T>& x)
            {
                std::swap(head,x.head);
            }
            void push_back(const T& x)
            {
                listnode *cur= new listnode(x);
                if(head->next==head)
                {
                    head->next=cur;
                    cur->prev=head;
                    cur->next=head;
                    head->prev=cur;
                }
                else
                {
                    listnode *tail=head->prev;
                    tail->next=cur;
                    cur->prev=tail;
                    cur->next=head;
                    head->prev=cur;
                }
            }
            void push_front(const T& x)
            {
                listnode *cur=new listnode(x);
                cur->prev=head;
                cur->next=head->next;
                head->next->prev=cur;
                head->next=cur;
            }
            void pop_front()
            {
                listnode *cur=head->next;
                head->next=cur->next;
                cur->next->prev=head;
                delete cur;
                cur=nullptr;
            }
            void pop_back()
            {
                listnode *cur=head->prev;
                head->prev=cur->prev;
                cur->prev->next=head;
                delete cur;
                cur=nullptr;
            }
        private:
            listnode *head;
            //初始化
            void init()
            {
                head->next=head;
                head->prev=head;
            }
    };
}
